/**
 * 
 */
package org.shark.jdbcTemplateTool.utils.sql;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.shark.jdbcTemplateTool.exception.SqlNotFoundException;
import org.shark.jdbcTemplateTool.utils.CacheUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author lenovo
 * @description
 * @date 2016年8月17日
 */
public abstract class AbstractBaseSqlLoad {
	
	protected static final Logger log = LoggerFactory.getLogger(SqlFileUtil.class);

    /**
     * 过滤掉的sql关键字
     */
    protected static final List<String> badKeyWordList = new ArrayList<String>();
    
    /**
     * 
     */
    protected String cacheName = "Jdbc-Template-Sql";
    
    protected String classRootPath = "";
    
    /**
     * 加载关键字到List
     */
    static {
        String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +
                "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
                "table|from|grant|use|group_concat|column_name|" +
                "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +
                "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";
        badKeyWordList.addAll(Arrays.asList(badStr.split("\\|")));
    }
    
    /**
     * sql查询关键字过滤效验
     * @param queryStr
     * @return
     */
    public boolean keywordVali(String queryStr) {
        queryStr = queryStr.toLowerCase();//统一转为小写
        for (String badKeyWord : badKeyWordList) {
            if (queryStr.indexOf(badKeyWord) >= 0) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 获取SQL，固定SQL
     * @param sqlId
     * @return
     * @throws SqlNotFoundException 
     */
    public String getSql(String sqlId) throws SqlNotFoundException {
        String sql = get(sqlId);
        if(null == sql || sql.isEmpty()){
            throw new SqlNotFoundException(sqlId);
        }
        
        return sql.replaceAll("[\\s]{2,}", " ");
    }

    
    /**
     * 清楚加载的sql
     */
    public void destory() {
    	CacheUtil.getInstant().removeAll(cacheName);
    }
    
    protected boolean containsKey(String key) {
    	if (!CacheUtil.getInstant().containKey(cacheName, key)) {
    		return false;
    	}
    	String sql = CacheUtil.getInstant().get(cacheName, key);
    	return !StringUtils.isEmpty(sql);
    }
   
    protected void putCache(String key, String sql) {
    	CacheUtil.getInstant().put(cacheName, key, sql);
    }
    
    private String get(String key) {
    	return CacheUtil.getInstant().get(cacheName, key);
    }
    
    /**
     * 递归查找文件
     * @param baseFile
     * @param sqlFiles
     */
    protected void findFiles(File baseFile, List<File> sqlFiles) {
        if (!baseFile.isDirectory()) {
            if (baseFile.getName().endsWith(getFileExt())) {
                sqlFiles.add(baseFile);
            }
        } else {
            File[] fileList = baseFile.listFiles();
            for (File file : fileList) {
                if (file.isDirectory()) {
                    findFiles(file, sqlFiles);
                    
                } else {
                    if (file.getName().endsWith(getFileExt())) {
                        sqlFiles.add(file);
                    }
                }
            }
        }
    }

	protected List<File> scanFiles(String cacheName) {
		if (cacheName != null && !"".equals(cacheName)) {
    		this.cacheName = cacheName;
    	}
    	
        classRootPath = SqlXmlUtil.class.getClassLoader().getResource("").getFile();
        try {
            classRootPath = java.net.URLDecoder.decode(classRootPath, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("初始化加载sql：获取classRootPath异常");
        }
        File file = new File(classRootPath);
        List<File> files = new ArrayList<File>();
        findFiles(file, files);
		return files;
	}
	
	/**
	 * @param key
	 * @return
	 */
	public boolean containKey(String key) {
		return CacheUtil.getInstant().containKey(cacheName, key);
	}
    
    protected abstract String getFileExt();
}
